package com.cal.calonecal.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cal.calonecal.common.Response;
import com.cal.calonecal.mapper.ChooseMapper;
import com.cal.calonecal.mapper.ProblemMapper;
import com.cal.calonecal.mapper.TagMapper;
import com.cal.calonecal.mapper.TagProblemMapper;
import com.cal.calonecal.pojo.entity.Choose;
import com.cal.calonecal.pojo.entity.Problem;
import com.cal.calonecal.pojo.entity.Tag;
import com.cal.calonecal.pojo.entity.TagProblem;
import com.cal.calonecal.service.IProblemService;
import com.cal.calonecal.utils.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author 76004
 * @apiNote
 * @date 2023/6/17 0:19
 */
@Service
public class ProblemServiceImpl implements IProblemService {
    @Autowired
    private ProblemMapper problemMapper;

    @Autowired
    private ChooseMapper chooseMapper;

    @Autowired
    private TagProblemMapper tagProblemMapper;

    @Autowired
    private TagMapper tagMapper;

    @Autowired
    private UserUtil userUtil;
    @Override
    public Response<Void> add(Problem problem) {
        problem.setStatus(0);
        problem.getTags().stream().peek(tagName->{
            Tag tag = new Tag();
            //新增tag
            if(tagMapper.selectCount(new QueryWrapper<Tag>().eq("name", tagName)) == 0){
                tag.setName(tagName);
                tagMapper.insert(tag);
            }
            tag = tagMapper.selectOne(new QueryWrapper<Tag>().eq("name", tagName));
            TagProblem tagProblem = new TagProblem();
            tagProblem.setProblemId(problem.getId());
            tagProblem.setTagId(tag.getId());
            tagProblem.setName(tagName);
            tagProblemMapper.insert(tagProblem);
        }).collect(Collectors.toList());
        //添加选项
        problem.getChooses().stream().peek(choose -> {
            choose.setStatus(0);
            chooseMapper.insert(choose);
        }).collect(Collectors.toList());
        return Response.success();
    }

    @Override
    public Response<Void> delete(Long id) {
        problemMapper.deleteById(id);
        return Response.success();
    }

    @Override
    public Response<Void> update(Problem problem) {
        problemMapper.updateById(problem);
        return Response.success();
    }

    @Override
    public Response<IPage<Problem>> selectByUserId(Integer pageNum, Integer pageSize) {
        IPage<Problem> problems = problemMapper.selectPage(new Page<Problem>(pageNum, pageSize), new QueryWrapper<Problem>().eq("user_id", userUtil.getUserId()).eq("type",1));
        for(Problem problem: problems.getRecords()) {
            problem.setChooses(chooseMapper.selectList(new QueryWrapper<Choose>().eq("problem_id", problem.getId())));
            problem.setTags(tagProblemMapper.selectList(new QueryWrapper<TagProblem>().eq("problem_id", problem.getId())).stream().map(TagProblem::getName).collect(Collectors.toList()));
        }
        return Response.success(problems);
    }

    @Override
    public Response<IPage<Problem>> selectPage(Integer pageNum, Integer pageSize) {
        IPage<Problem> problemIPage = problemMapper.selectPage(new Page<Problem>(pageNum, pageSize), null);
        return Response.success(problemIPage.setRecords(problemIPage.getRecords().stream().map(problem -> {
            problem.setTags(tagProblemMapper.selectList(new QueryWrapper<TagProblem>().eq("problem_id", problem.getId())).stream().map(tagProblem -> {
                return tagProblem.getName();
            }).collect(Collectors.toList()));
            return problem;
        }).collect(Collectors.toList())));
    }

    @Override
    public Response<Problem> selectById(long id) {
        Problem problem = problemMapper.selectById(id);
        problem.setChooses(chooseMapper.selectList(new QueryWrapper<Choose>().eq("problem_id", problem.getId())));
        problem.setTags(tagProblemMapper.selectList(new QueryWrapper<TagProblem>().eq("problem_id", problem.getId())).stream().map(tagProblem -> {
            return tagProblem.getName();
        }).collect(Collectors.toList()));
        return Response.success(problem);
    }

    @Override
    public Response<List<Problem>> selectByPaperId(long paperId) {
        List<Problem> problems = problemMapper.selectList(new QueryWrapper<Problem>().eq("paper_id", paperId));
        problems = problems.stream().map(problem -> {
            problem.setChooses(chooseMapper.selectList(new QueryWrapper<Choose>().eq("problem_id", problem.getId())));
            problem.setTags(tagProblemMapper.selectList(new QueryWrapper<TagProblem>().eq("problem_id", problem.getId())).stream().map(TagProblem::getName).collect(Collectors.toList()));
            return problem;
        }).collect(Collectors.toList());
        return Response.success(problems);
    }

    @Override
    public Response<Void> addTag2Problem(String tagName, long problemId) {
        long count = tagMapper.selectCount(new QueryWrapper<Tag>().eq("name", tagName));
        if(count == 0){
            Tag tag = new Tag();
            tag.setName(tagName);
            tagMapper.insert(tag);
        }
        Tag tag = tagMapper.selectOne(new QueryWrapper<Tag>().eq("name", tagName));
        TagProblem tagProblem = new TagProblem();
        tagProblem.setProblemId(problemId);
        tagProblem.setTagId(tag.getId());
        return Response.success();
    }

    @Override
    public Response<IPage<Problem>> selectByTagId(long tagId, Integer pageNum, Integer pageSize) {
       IPage<TagProblem>tagProblemIPage = tagProblemMapper.selectPage(new Page<>(pageNum, pageSize),
               new QueryWrapper<TagProblem>().eq("tag_id", tagId));
       Page<Problem> problemPage = BeanUtil.copyProperties(tagProblemIPage, Page.class, "records");
       return Response.success(problemPage.setRecords(tagProblemIPage.getRecords().stream().map(tag -> {
           return problemMapper.selectById(tag.getProblemId());
       }).collect(Collectors.toList())));
    }

    @Override
    public Response<IPage<Problem>> selectByTagName(String tagName, Integer pageNum, Integer pageSize) {
        IPage<TagProblem>tagProblemIPage = tagProblemMapper.selectPage(new Page<>(pageNum, pageSize),
                new QueryWrapper<TagProblem>().eq("name", tagName));
        Page<Problem> problemPage = BeanUtil.copyProperties(tagProblemIPage, Page.class, "records");
        return Response.success(problemPage.setRecords(tagProblemIPage.getRecords().stream().map(tag -> {
            return problemMapper.selectById(tag.getProblemId());
        }).filter(Objects::nonNull).collect(Collectors.toList())));
    }

    @Override
    public Response addChoose(Choose choose) {
        chooseMapper.insert(choose);
        return Response.success();
    }

    @Override
    public Response delChoose(Long choseId) {
        chooseMapper.deleteById(choseId);
        return Response.success();
    }

    @Override
    public Response addTag(Tag tag, Long problemId) {
        if(0 == tagMapper.selectCount(new QueryWrapper<Tag>().eq("name", tag.getName()))){
            tagMapper.insert(tag);
        }
        TagProblem tagProblem = new TagProblem();
        tagProblem.setTagId(tag.getId());
        tagProblem.setName(tagProblem.getName());
        tagProblemMapper.insert(tagProblem);
        return Response.success();
    }

    @Override
    public Response delTag(String tagName, Long problemId) {
        tagProblemMapper.delete(new QueryWrapper<TagProblem>().eq("name", tagName).eq("problem_id", problemId));
        return Response.success();
    }


}
